<?php

require_once 'Zend/Db/Table/Abstract.php';
require_once 'Naneau/Db/Table/Row.php';

class Naneau_Db_Table extends Zend_Db_Table_Abstract {

    /**
     * array of extra fields
     *
     * @var array
     */
    private $_extraFields = array();

    /**
     * modifiers
     *
     * @var array
     */
    private $_modifiers = array();

    public function __construct(array $config = array())
    {
        if (!isset($config['rowClass'])) {
            $config['rowClass'] = 'Naneau_Db_Table_Row';
            $config['rowsetClass'] = 'Naneau_Db_Table_Rowset';
        }
        //boeh!

        parent::__construct($config);

        if (method_exists($this, 'setup')) {
            $this->setup();
        }
    }

    /**
     * add an extra field to the row definition
     *
     * @param string $name
     * @param string|array $fieldFunc
     */
    protected function addExtraField($name, $fieldFunc)
    {
        $this->_extraFields[$name] = $fieldFunc;
    }

    /**
     * get an extra field
     * 
     * @param Naneau_Db_Row $row
     * @param string $what
     * @return mixed
     * @throws Zend_Db_Table_Row_Exception
     */
    public function getExtraField($row, $what)
    {
        if (!array_key_exists($what, $this->_extraFields)) {
            //field doesn't exist in extra fields
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception("Specified column \"$what\" is not in the row");
        }

        $func = $this->_extraFields[$what];
        //the function
        $args = array($row, $what);
        //the arguments (an copy of this row is given to the function to work with)

        if (is_array($func)) {
            //method of some class or object
            return call_user_method_array($func[1], $func[0], $args);
        } else {
            //plain function
            return call_user_func_array($func, $args);
        }
        //return the result of a function
    }

    /**
     * get a modified field value, if a modifier has been registered
     *
     * @param Naneau_Db_Table_Row $row
     * @param string $what
     * @param mixed $value
     * @return mixed
     */
    public function getModifiedValue($row, $what, $value) {
        if (array_key_exists($what, $this->_modifiers)) {

            $modifier = $this->_modifiers[$what];
            $this->_modified[$what] = $modifier->modify($value, $row);
            //get the modified value

            return $this->_modified[$what];
            //cache it
        }

        return $value;
        //return "regular" value
    }

    /**
     * get an unModified value, if a modifier has been registered
     *
     * @param Naneau_Db_Table_Row $row
     * @param string $what
     * @param mixed $value
     * @return mixed
     */
    public function getUnModifiedValue($row, $what, $value) {
        if (array_key_exists($what, $this->_modifiers)) {
            $modifier = $this->_modifiers[$what];
            $value = $modifier->unModify($value, $row);
        }
        return $value;
    }

    /**
	 * add a modifier to the model
	 *
	 * @param string $field
	 * @param Naneau_Db_Table_Modifier $modifier
	 */
    protected function addModifier($field, $modifier) {
        $this->_modifiers[$field] = $modifier;
    }
}